Shorten the hypercall table.
/*
- * linux/arch/i386/entry.S
+ * Hypercall and fault low-level handling routines.
*
- * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright (c) 2002-2004, K A Fraser
+ * Copyright (c) 1991, 1992 Linus Torvalds
*/
/*
- * entry.S contains the system-call and fault low-level handling routines.
- * This also contains the timer-interrupt handler, as well as all interrupts
- * and faults that can result in a task-switch.
+ * The idea for callbacks from monitor -> guest OS
+ * ===============================================
*
- * Stack layout in 'ret_from_system_call':
- * 0(%esp) - %ebx
- * 4(%esp) - %ecx
- * 8(%esp) - %edx
- * C(%esp) - %esi
- * 10(%esp) - %edi
- * 14(%esp) - %ebp
- * 18(%esp) - %eax
- * 1C(%esp) - %ds
- * 20(%esp) - %es
- * 24(%esp) - %fs
- * 28(%esp) - %gs
- * 2C(%esp) - orig_eax
- * 30(%esp) - %eip
- * 34(%esp) - %cs
- * 38(%esp) - %eflags
- * 3C(%esp) - %oldesp
- * 40(%esp) - %oldss
- *
- * "current" is in register %ebx during any slow entries.
- */
-/* The idea for callbacks from monitor -> guest OS.
- *
* First, we require that all callbacks (either via a supplied
* interrupt-descriptor-table, or via the special event or failsafe callbacks
* in the shared-info-structure) are to ring 1. This just makes life easier,
CF_MASK = 0x00000001
IF_MASK = 0x00000200
NT_MASK = 0x00004000
-
-
#define SAVE_ALL_NOSEGREGS \
cld; \
ALIGN
/*
* HYPERVISOR_multicall(call_list, nr_calls)
- * Execute a list of 'nr_calls' system calls, pointed at by 'call_list'.
+ * Execute a list of 'nr_calls' hypercalls, pointed at by 'call_list'.
* This is fairly easy except that:
* 1. We may fault reading the call list, and must patch that up; and
* 2. We cannot recursively call HYPERVISOR_multicall, or a malicious
pushl 4(%ebx) # args[0]
multicall_fault6:
movl (%ebx),%eax # op
- andl $255,%eax
- call *SYMBOL_NAME(hypervisor_call_table)(,%eax,4)
+ andl $(NR_hypercalls-1),%eax
+ call *SYMBOL_NAME(hypercall_table)(,%eax,4)
multicall_return_from_call:
multicall_fault7:
movl %eax,24(%ebx) # args[5] == result
loop multicall_loop
popl %ebx
xorl %eax,%eax
- jmp ret_from_hypervisor_call
+ jmp ret_from_hypercall
.section __ex_table,"a"
.align 4
addl $4,%esp
popl %ebx
movl $-EFAULT,%eax
- jmp ret_from_hypervisor_call
+ jmp ret_from_hypercall
.previous
ALIGN
iret
ALIGN
-ENTRY(hypervisor_call)
+ENTRY(hypercall)
pushl %eax # save orig_eax
SAVE_ALL
GET_CURRENT(%ebx)
- andl $255,%eax
- call *SYMBOL_NAME(hypervisor_call_table)(,%eax,4)
+ andl $(NR_hypercalls-1),%eax
+ call *SYMBOL_NAME(hypercall_table)(,%eax,4)
-ret_from_hypervisor_call:
+ret_from_hypercall:
movl %eax,EAX(%esp) # save the return value
test_all_events:
jmp SYMBOL_NAME(io_check_error)
.data
-ENTRY(hypervisor_call_table)
+ENTRY(hypercall_table)
.long SYMBOL_NAME(do_set_trap_table) /* 0 */
.long SYMBOL_NAME(do_mmu_update)
.long SYMBOL_NAME(do_set_gdt)
.long SYMBOL_NAME(do_console_io)
.long SYMBOL_NAME(do_physdev_op)
.long SYMBOL_NAME(do_update_va_mapping_otherdomain) /* 20 */
- .rept NR_syscalls-((.-hypervisor_call_table)/4)
- .long SYMBOL_NAME(do_ni_syscall)
+ .rept NR_hypercalls-((.-hypercall_table)/4)
+ .long SYMBOL_NAME(do_ni_hypercall)
.endr
next:
current_vector += 8;
- /* XXX Skip the guestOS -> Xen syscall vector! XXX */
- if (current_vector == HYPERVISOR_CALL_VECTOR) goto next;
- /* XXX Skip the Linux/BSD fast-trap vector! XXX */
+ /* Skip the hypercall vector. */
+ if (current_vector == HYPERCALL_VECTOR) goto next;
+ /* Skip the Linux/BSD fast-trap vector. */
if (current_vector == 0x80) goto next;
if (current_vector > FIRST_SYSTEM_VECTOR) {
asmlinkage void do_IRQ(struct pt_regs regs)
{
- unsigned int irq = regs.orig_eax & 0xff;
+ unsigned int irq = regs.orig_eax;
irq_desc_t *desc = &irq_desc[irq];
struct irqaction *action;
static struct tss_struct doublefault_tss;
static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE];
-asmlinkage int hypervisor_call(void);
+asmlinkage int hypercall(void);
asmlinkage void lcall7(void);
asmlinkage void lcall27(void);
set_intr_gate(19,&simd_coprocessor_error);
/* Only ring 1 can access monitor services. */
- _set_gate(idt_table+HYPERVISOR_CALL_VECTOR,14,1,&hypervisor_call);
+ _set_gate(idt_table+HYPERCALL_VECTOR,14,1,&hypercall);
/* CPU0 uses the master IDT. */
idt_tables[0] = idt_table;
}
/*
- * Simple syscalls.
+ * Simple hypercalls.
*/
long do_xen_version(int cmd)
return (XEN_VERSION<<16) | (XEN_SUBVERSION);
}
-long do_ni_syscall(void)
+long do_ni_hypercall(void)
{
- /* No-op syscall. */
+ /* No-op hypercall. */
return -ENOSYS;
}
#define barrier() __asm__ __volatile__("": : :"memory")
-#define NR_syscalls 256
+#define NR_hypercalls 32
#ifndef NDEBUG
#define MEMORY_GUARD
#define NR_IRQS (256 - FIRST_EXTERNAL_VECTOR)
-#define HYPERVISOR_CALL_VECTOR 0x82
+#define HYPERCALL_VECTOR 0x82
/*
* Vectors 0x30-0x3f are used for ISA interrupts.
/*
* First APIC vector available to drivers: (vectors 0x40-0xee)
* we start at 0x41 to spread out vectors evenly between priority
- * levels. (0x82 is the syscall vector)
+ * levels. (0x82 is the hypercall vector)
*/
#define FIRST_DEVICE_VECTOR 0x41
#define FIRST_SYSTEM_VECTOR 0xef
#define IRQ_NAME2(nr) nr##_interrupt(void)
#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
-/*
- * SMP has a few special interrupts for IPI messages
- */
-
- /* there is a second layer of macro just to get the symbolic
- name for the vector evaluated. This change is for RTLinux */
#define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
#define XBUILD_SMP_INTERRUPT(x,v)\
asmlinkage void x(void); \
__asm__( \
"\n"__ALIGN_STR"\n" \
SYMBOL_NAME_STR(x) ":\n\t" \
- "pushl $"#v"-256\n\t" \
+ "pushl $"#v"\n\t" \
SAVE_ALL \
SYMBOL_NAME_STR(call_##x)":\n\t" \
"call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
__asm__( \
"\n"__ALIGN_STR"\n" \
SYMBOL_NAME_STR(x) ":\n\t" \
- "pushl $"#v"-256\n\t" \
+ "pushl $"#v"\n\t" \
SAVE_ALL \
"movl %esp,%eax\n\t" \
"pushl %eax\n\t" \
"call " SYMBOL_NAME_STR(do_IRQ) "\n\t" \
"jmp ret_from_intr\n");
-/*
- * subtle. orig_eax is used by the signal code to distinct between
- * system calls and interrupted 'random user-space'. Thus we have
- * to put a negative value into orig_eax here. (the problem is that
- * both system calls and IRQs want to have small integer numbers in
- * orig_eax, and the syscall code has won the optimization conflict ;)
- *
- * Subtle as a pigs ear. VY
- */
-
#define BUILD_IRQ(nr) \
asmlinkage void IRQ_NAME(nr); \
__asm__( \
"\n"__ALIGN_STR"\n" \
SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
- "pushl $"#nr"-256\n\t" \
+ "pushl $"#nr"\n\t" \
"jmp common_interrupt");
extern unsigned long prof_cpu_mask;
#include <xen/irq.h>
+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
+{
#if defined(CONFIG_X86_IO_APIC)
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {
if (IO_APIC_IRQ(i))
send_IPI_self(IO_APIC_VECTOR(i));
-}
-#else
-static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
#endif
+}
#endif /* _ASM_HW_IRQ_H */
#define R12 24
#define RBP 36
#define RBX 40
-/* arguments: interrupts/non tracing syscalls only save upto here*/
+/* arguments: interrupts/hypercalls only save upto here*/
#define R11 48
#define R10 56
#define R9 64
#define RDI 112
#define ORIG_RAX 120 /* = ERROR */
/* end of arguments */
-/* cpu exception frame or undefined in case of fast syscall. */
+/* cpu exception frame or undefined in case of fast hypercall. */
#define RIP 128
#define CS 136
#define EFLAGS 144
unsigned long r12;
unsigned long rbp;
unsigned long rbx;
-/* arguments: non interrupts/non tracing syscalls only save upto here*/
+/* arguments: non interrupts/hypercalls only save upto here*/
unsigned long r11;
unsigned long r10;
unsigned long r9;